/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simchewie.algorithms;

import java.awt.Point;
import java.util.Stack;
import simchewie.Labyrinth;

/**
 *
 * @author willi
 */
public class ImmerRechtsMitBrain implements Wookie {

    int orientation = 0;
    Point pos = new Point(0, 0);
    private String[] directions = new String[]{"N", "O", "S", "W"};
    public Labyrinth labyrinth = null;
    private Stack<Integer> brain = new Stack<Integer>();
    boolean lastturn = false;
    boolean isFinished = false;
    boolean hasSeenFinish = false;
    private boolean[][] washere = new boolean[10][12];

    public ImmerRechtsMitBrain(Labyrinth f, int x, int y) {
        labyrinth = f;
        pos.x = x;
        pos.y = y;
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 12; j++) {
                washere[i][j] = false;

            }
        }
    }

    public void forward() {
        if (orientation == 0 && pos.y - 1 >= 0) {
            pos.y--;
        } else if (orientation == 1 && pos.x + 1 <= 9) {
            pos.x++;
        } else if (orientation == 2 && pos.y + 1 <= 11) {
            pos.y++;
        } else if (orientation == 3 && pos.x - 1 >= 0) {
            pos.x--;
        }
        lastturn = false;
    }

    private void turnLeft() {
        orientation = (orientation - 1) % 4;
        if (orientation < 0) {
            orientation = 4 + orientation;
        }
        lastturn = true;


    }


    private boolean checkOrientationSTD(int x, int y, int o) {
        if (hasSeenFinish) {

            if (x == 0) {

                if (labyrinth.checkOrientation(x, y, 3)) {
                    isFinished = true;
                }
            }

            if (x == 9) {

                if (labyrinth.checkOrientation(x, y, 1)) {
                    isFinished = true;
                }

            }

            if (y == 0) {

                if (labyrinth.checkOrientation(x, y, 0)) {
                    isFinished = true;
                }

            }

            if (y == 11) {

                if (labyrinth.checkOrientation(x, y, 2)) {
                    isFinished = true;
                }

            }
            return labyrinth.checkOrientation(x, y, o);
        } else {
            if (x == 0 && orientation == 3) {
                return false;
            }

            if (x == 9 && orientation == 1) {
                return false;
            }

            if (y == 0 && orientation == 0) {
                return false;
            }

            if (y == 11 && orientation == 2) {
                return false;
            }

            return labyrinth.checkOrientation(x, y, o);

        }
    }

    private void turnRight() {
        orientation = (orientation + 1) % 4;
        lastturn = true;
    }

    public Point getPosition() {
        return pos;
    }

    public int getOrientation() {
        return orientation;
    }

    public String writeOrientation() {
        return directions[orientation];
    }

    public void nextstep() {
        if (labyrinth.isFinish(pos.x, pos.y)) {
            hasSeenFinish = true;
            turnRight();
            turnRight();

        }

        washere[pos.x][pos.y] = true;

        if (hasSeenFinish) {
           
                int bpop = brain.pop();
                if (bpop == 0) {
                    forward();

                } else if (bpop == 1) {
                    turnLeft();
                } else if (bpop == 2) {
                    turnRight();
                }
            
        } else {
            if (checkOrientationSTD(pos.x, pos.y, (orientation + 1) % 4)) {
                if (lastturn && checkOrientationSTD(pos.x, pos.y, orientation)) {
                    forward();
                    brain.push(0);
                } else {
                    turnRight();
                    brain.push(1);
                }
            } else if (checkOrientationSTD(pos.x, pos.y, orientation)) {
                forward();
                brain.push(0);
            } else {
                if (checkOrientationSTD(pos.x, pos.y, (orientation + 3) % 4)) {
                    turnLeft();
                    brain.push(2);
                } else {
                    turnRight();
                    brain.push(1);
                }
            }
        }
    }

    public boolean isFinished() {
        return isFinished;
    }

    public boolean[][] getWasHere() {
        return washere;
    }
}
